package world0;

import java.util.ArrayList;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

import world0.gui.UserInterface;
import world0.items.Item;

public abstract class GenericChar extends GameObject {

	private int index;
	public Skill skill;

	/* Set properties + default value */
	private String name = "GenericChar_"; // add index @ output
	private int live = 10;
	private int fullLive;
	private int energy = 10;
	private String energyTyp = "Mana";
	private boolean isGod = false;
	private boolean isAttitude = true; // true = friendly
	private boolean isShop = false;
	private boolean isHoldItems = false;
	
	private boolean isRandomWalk = true;
	private int randomWalkRadius = 100; // Not a fix radius!
	private boolean isFly = false;
	private boolean isDefaultHitbox = true;
	private float speed = 0.5f;
	private boolean isTalking = false;
	private int maxJump = 50;
	private float fallSpeed = 1.5f;
	private float startFallSpeed;
	private float resetX;
	private float resetY;
	
	private int waitDmg = 120;
	
	protected ArrayList<Item> itemList;
	
	public GenericChar(float x, float y, Image image, int index, int state) {
		super(x, y, image, state);
		this.index = index;

		initGenericChar();
	}

	private void initGenericChar() {
		resetX = getX();
		resetY = getY();
		
		fullLive = live;
		startFallSpeed = fallSpeed;

		itemList = new ArrayList<Item>();
		
		if (!isFly) {
			if (isDefaultHitbox) {
				super.collision = new CollisionDetection(getX(), getY(), image, 4);
			}
		}
		
		/* Skills */
		skill = new Skill();
	}

	@Override
	public void draw(Graphics g) throws SlickException {

		if (isAttitude) {
			g.setColor(Color.black);
		} else {
			g.setColor(Color.red);
		}
		String info = "Live: " + live + " lvl: " + skill.getLevel();
		g.drawString(info, getX() - (g.getFont().getWidth(info) / 2),
				getY() - 50);
		g.drawString(name, getX() - (g.getFont().getWidth(name) / 2),
				getY() - 70);

		// super.collision.debugDraw(g);
	}

	public void update(int delta, ArrayList<LevelObject> solidList,
			ArrayList<LevelObject> slopeList, ArrayList<Mob> mobList,
			Player player) {

		if (!isFly) {
			bodyFall(speed, fallSpeed, solidList, slopeList);

			if (isRandomWalk && !isTalking) {
				randomWalk(solidList, slopeList);
				walk(randomWalkRadius, speed);
			}
			
			if(super.collision.debugCheckCollisionLevelObject(solidList)) {
				setY(getY() - 0.5f);
			}
			
			if(collision.mainCheckCollisionSlope(slopeList)) {
				fallSpeed = 1;
			} else {
				fallSpeed = startFallSpeed;
			}
			
			super.collision.update(getX(), getY());
		}
		
		if(isAttitude) {
			if(super.collision.checkCollisionMob(mobList, index)) {
				takeDamage();
			}
		}
		
		/* Out of level reset */
		if(getY() > 1000) {
			resetPosition();
		}
	}
		
	/* Overload for NPCs - no Interface*/
	public void giveItem(Item item, UserInterface userInterface) {
		itemList.add(item);
		
		userInterface.placeItemToFreeSlot(item);
		userInterface.setItemList(itemList);
	}
	
	public void resetPosition() {
		setX(resetX);
		setY(resetY);
	}
	
	public void resetChar() {
		setX(resetX);
		setY(resetY);
		setLive(fullLive);
		System.out.println("Char. reseted");
	}
	
	private void takeDamage() {
		if(waitDmg >= 120 ) {
			live -= 1;
			waitDmg = 0;
		}
		waitDmg += 1;
	}
		
	public boolean isHoldItems() {
		return isHoldItems;
	}


	public void setHoldItems(boolean isHoldItems) {
		this.isHoldItems = isHoldItems;
	}

	public float getFallSpeed() {
		return fallSpeed;
	}

	public void setFallSpeed(float fallSpeed) {
		this.fallSpeed = fallSpeed;
	}

	public int getMaxJump() {
		return maxJump;
	}

	public void setMaxJump(int maxJump) {
		this.maxJump = maxJump;
	}

	public float getSpeed() {
		return speed;
	}

	public void setSpeed(float speed) {
		this.speed = speed;
	}

	public int getRandomWalkRadius() {
		return randomWalkRadius;
	}

	public void setRandomWalkRadius(int randomWalkRadius) {
		this.randomWalkRadius = randomWalkRadius;
	}

	public boolean isDefaultHitbox() {
		return isDefaultHitbox;
	}

	public void setDefaultHitbox(boolean isDefaultHitbox) {
		this.isDefaultHitbox = isDefaultHitbox;
	}

	public boolean isFly() {
		return isFly;
	}

	public void setFly(boolean isFly) {
		this.isFly = isFly;
	}

	public boolean isRandomWalk() {
		return isRandomWalk;
	}

	public void setRandomWalk(boolean isRandomWalk) {
		this.isRandomWalk = isRandomWalk;
	}

	public void setEnergy(int energy, String energyTyp) {
		this.energy = energy;
		this.energyTyp = energyTyp;
	}

	public void setEnergy(int energy) {
		this.energy = energy;
	}

	public void setEnergyTyp(String energyTyp) {
		this.energyTyp = energyTyp;
	}

	public int getEnergy() {
		return energy;
	}

	public String getEnergyTyp() {
		return energyTyp;
	}

	public boolean isShop() {
		return isShop;
	}

	public void setShop(boolean isShop) {
		this.isShop = isShop;
	}

	public int getIndex() {
		return index;
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public boolean isGod() {
		return isGod;
	}

	public void setGod(boolean isGod) {
		this.isGod = isGod;
	}

	public int getLive() {
		return live;
	}

	public void setLive(int live) {
		this.live = live;
	}

	public boolean isAttitude() {
		return isAttitude;
	}

	public void setAttitude(boolean isAttitude) {
		this.isAttitude = isAttitude;
	}

	public String getName() {
		return name;
	}

	protected void setName(String name) {
		this.name = name;
	}
}
